package com.daxt.controller.sysarchives;

import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;

import com.daxt.base.common.util.RedisUtil;
import com.daxt.common.exception.BaseException;
import com.daxt.mapper.sys.DicMapper;
import com.daxt.mapper.sys.RoleMapper;
import com.daxt.mapper.sys.UserClassifyMapper;
import com.daxt.model.constant.BaseConstants;
import com.daxt.model.dic.SystemConfigType;
import com.daxt.model.dic.VersionsMarkType;
import com.daxt.model.dto.BaseExportParam;
import com.daxt.model.dto.BaseQueryDto;
import com.daxt.model.dto.ClassifysTemplate;
import com.daxt.model.service.base.vo.Dic;
import com.daxt.model.service.base.vo.Role;
import com.daxt.model.service.base.vo.UserClassify;
import com.daxt.service.ArchivesService;
import com.daxt.utils.ArchivesUtil;
import com.daxt.utils.StringUtil;
import com.daxt.utils.file.FileBaseUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.daxt.common.result.Result;
import com.daxt.common.result.ResultCode;
import com.daxt.common.result.ResultUtil;
import com.daxt.mapper.archives.ArchivesDocMapper;
import com.daxt.mapper.sys.ArchivesClassMapper;
import com.daxt.model.service.archives.vo.ArchivesClass;
import com.daxt.model.service.archives.vo.ArchivesDoc;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Api(tags = "档案类型分类管理、类目管理")
@RestController
public class ArchivesClassController {

    @Autowired
    private ArchivesClassMapper archivesClassMapper;
    @Autowired
    private ArchivesDocMapper archivesDocMapper;
    @Autowired
    private DicMapper dicMapper;
    @Autowired
    private ArchivesService archivesService;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserClassifyMapper userClassifyMapper;


    @ApiOperation(value = "获取档案门类分类1", notes = "")
    @GetMapping("/archivesClass/{fondsId}/{typeId}")
    public Result<List<ArchivesClass>> list(@ApiParam("全宗Id") @PathVariable("fondsId") String fondsId,
                                            @ApiParam("门类ID") @PathVariable("typeId") String typeId,
                                            @RequestParam(value = "classId",required = false) Long classId) {


        QueryWrapper<ArchivesClass> queryWrapper = ArchivesUtil.builBaseQueryWrapper(new BaseQueryDto(fondsId,typeId));

        queryWrapper.eq("classType", "1");
        List<ArchivesClass> list = archivesClassMapper.selectList(queryWrapper);
        List<ArchivesClass> resultList = new ArrayList<ArchivesClass>();
        if (list != null && list.size() > 0) {

            Map m = new HashMap();
            for (int i = 0; i < list.size(); i++) {
                ArchivesClass archivesClass = list.get(i);
                if (archivesClass.getParentId().intValue() == 0) resultList.add(archivesClass);
                buildParentId(list.get(i));

            }


        }
        StringBuilder treeParentId=new StringBuilder();
        setClassChildren(list, resultList,classId,treeParentId);

        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), null, resultList);
    }


    @ApiOperation(value = "获取档案门类分类2", notes = "")
    @GetMapping("/archivesClassList/{fondsId}/{typeId}")
    public Result<List<ArchivesClass>> list1(@ApiParam("全宗Id") @PathVariable("fondsId") String fondsId,
                                             @ApiParam("门类ID") @PathVariable("typeId") String typeId,
                                             @RequestParam(value = "classId",required = false) Long classId) {

        QueryWrapper<ArchivesClass> queryWrapper = ArchivesUtil.builBaseQueryWrapper(new BaseQueryDto(fondsId,typeId));
        queryWrapper.orderByAsc("sort");

        List<ArchivesClass> list = archivesClassMapper.selectList(queryWrapper);
        List<ArchivesClass> resultList = new ArrayList<>();
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                ArchivesClass archivesClass = list.get(i);
                if (archivesClass.getParentId().intValue() == 0)
                    resultList.add(archivesClass);
                archivesClass.setTreeParentId(archivesClass.getId().toString());
            }
        }

        //list排序 正序
        Collections.sort(resultList, Comparator.comparing(ArchivesClass::getSort));

        StringBuilder treeParentId=new StringBuilder();
        setClassChildren(list, resultList,classId,treeParentId);

        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), null, resultList);
    }


    private void setClassChildren(List<ArchivesClass> list, List<ArchivesClass> resultList,Long classId,StringBuilder treeParentId) {
        for (int i = 0; i < resultList.size(); i++) {
            ArchivesClass archivesClass = resultList.get(i);
            if(archivesClass.getId()==classId){
                archivesClass.setChoose(true);
            }
            for (int j = 0; j < list.size(); j++) {
                ArchivesClass archivesClassTemp = list.get(j);
                if (archivesClass.getId().intValue() == archivesClassTemp.getParentId().intValue()) {
                    List<ArchivesClass> children = archivesClass.getChildren();
                    if(archivesClassTemp.getId()==classId){
                        archivesClassTemp.setChoose(true);
                    }
                    /*if(treeParentId.length()<=0){
                        treeParentId.append(archivesClass.getId().toString());
                        archivesClass.setTreeParentId(treeParentId.toString());
                    }*/
                    treeParentId.append(archivesClass.getTreeParentId());
                    treeParentId.append("-");
                    treeParentId.append(archivesClassTemp.getId());
                    archivesClassTemp.setTreeParentId(treeParentId.toString());

                    children.add(archivesClassTemp);
                    archivesClass.setChildren(children);

                    treeParentId.delete(0,treeParentId.length());
                }
            }
            List<ArchivesClass> children = archivesClass.getChildren();

            Collections.sort(children, Comparator.comparing(ArchivesClass::getSort));

            setClassChildren(list, children,classId,treeParentId);
            archivesClass.setChildren(children);
            resultList.set(i, archivesClass);
        }
    }


    @ApiOperation(value = "添加档案分类", notes = "")
    @PostMapping("/archivesClass")
    @Transactional(rollbackFor = Exception.class)
    public Result<List<ArchivesClass>> save(@RequestBody @Valid ArchivesClass archivesClass) {
        if (archivesClass.getSort() == null)
            archivesClass.setSort(1);
        if ("1".equals(archivesClass.getClassType())){
            if(archivesService.verifyClassNumRepetition(archivesClass) ) return ResultUtil.error("分类号重复");
            archivesClass.setIsCatalog("1");
        }

        int rows = archivesClassMapper.insert(archivesClass);

        //根据全宗查到对应角色
        if(rows>0){
            QueryWrapper<Role> roleQueryWrapper=new QueryWrapper<>();
            roleQueryWrapper.eq("fondsId",archivesClass.getFondsId());
            List<Role> roleList= roleMapper.selectList(roleQueryWrapper);
            //为对应角色设置分类权限
            for(Role role:roleList){
                UserClassify userClassify=new UserClassify();
                userClassify.setClassifyId(archivesClass.getId());
                userClassify.setRoleId(role.getId());
                userClassify.setType(2);
                //fondsId+typeId+父级Id+自己id
                userClassify.setTreeId(archivesClass.getTreeParentId()+"-"+archivesClass.getId());
                userClassifyMapper.insert(userClassify);
            }
        }

        return ResultUtil.data(rows > 0 ? ResultCode.RESULT_SUCCESS.getCode() : ResultCode.RESULT_ERROR.getCode(), null, null);
    }

    @ApiOperation(value = "修改档案分类门类", notes = "")
    @PutMapping("/archivesClass")
    public Result<List<ArchivesClass>> edit(@RequestBody @Valid ArchivesClass archivesClass) {

        if ("1".equals(archivesClass.getClassType())){

//            QueryWrapper<ArchivesClass> qw = ArchivesUtil.builBaseQueryWrapper(new BaseQueryDto(archivesClass.getFondsId(),archivesClass.getTypeId()));
//            qw.eq("parentId",archivesClass.getParentId());
//            qw.eq("classNum",archivesClass.getClassNum());
//            qw.notIn("id",archivesClass.getId());
//            int i =archivesClassMapper.selectCount(qw);
//            if(i > 0)return ResultUtil.error("分类号不能重复");

            if(archivesService.verifyClassNumRepetition(archivesClass) ) return ResultUtil.error("分类号重复");

        }
        int rows = archivesClassMapper.updateById(archivesClass);
        return ResultUtil.data(rows > 0 ? ResultCode.RESULT_SUCCESS.getCode() : ResultCode.RESULT_ERROR.getCode(), null, null);
    }

    @ApiOperation(value = "删除档案分类", notes = "")
    @DeleteMapping("/archivesClass")
    @Transactional(rollbackFor = Exception.class)
    public Result<List<ArchivesClass>> del(@RequestBody @Valid @NotEmpty List<String> ids) {
        QueryWrapper<ArchivesClass> queryWrapper = new QueryWrapper<ArchivesClass>();
        queryWrapper.in("id", ids);
        List<ArchivesClass> selectList = archivesClassMapper.selectList(queryWrapper);
        boolean flag = false;
        for (ArchivesClass archivesClass : selectList) {

            if("1".equals(archivesClass.getClassType())){

                QueryWrapper<ArchivesDoc> queryWrapperDoc = ArchivesUtil.builBaseQueryWrapper(new BaseQueryDto(archivesClass.getFondsId(),archivesClass.getTypeId(),archivesClass.getId().toString()));

                List<ArchivesDoc> selectList2 = archivesDocMapper.selectList(queryWrapperDoc);
                if (selectList2 != null && selectList2.size() > 0) {
                    flag = true;
                }
            }
        }
        QueryWrapper<ArchivesClass> queryWrapper1 = new QueryWrapper<ArchivesClass>();
        queryWrapper1.in("parentId", ids);
        List<ArchivesClass> selectList1 = archivesClassMapper.selectList(queryWrapper1);
        if (selectList1 != null && selectList1.size() > 0) {
            return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "请先删除分类下的节点！！！", null);
        }
        if (flag)
            return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "请先删除分类下的档案！！！", null);
        if (ids != null && ids.size() > 0) {
            archivesClassMapper.deleteBatchIds(ids);

            QueryWrapper<UserClassify> qWrapper = new QueryWrapper<UserClassify>();
            qWrapper.in("classifyId", ids);
            userClassifyMapper.delete(qWrapper);
        }

        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), null, null);
    }


    @ApiOperation(value = "导入分类配置", notes = "")
    @PostMapping("/archivesType/import")
    public Result<String> importFile(@RequestBody BaseExportParam exportParam,
                                     HttpServletRequest request, HttpServletResponse response) {

        String fondsId = exportParam.getFondsId();
        String typeId = exportParam.getTypeId();

        String url = exportParam.getUrl();
        if (StringUtils.isEmpty(url))
            return ResultUtil.data(ResultCode.RESULT_ERROR.getCode(), "请先上传要导入的文件！！！", null);

        String ossDir = RedisUtil.getSysConfig(SystemConfigType.OSS_DIR);
        List<ClassifysTemplate> oneList = FileBaseUtil.parseClassifysTemplate(ossDir + url);

        List<ArchivesClass> acList = new ArrayList<>();
        //新增分类
        insertClassByExcel(oneList, fondsId, typeId);



        return ResultUtil.data(ResultCode.RESULT_SUCCESS.getCode(), "", null);
    }


    ///
    /// private buil
    ///


    /**
     * @description: 将父类字段ID替换为分类ID
     * @author: lig
     * @date: 2021/6/22
     */
    private void buildParentId(ArchivesClass archivesClass) {
        if (archivesClass.getParentId().intValue() > 0) {
            ArchivesClass acBean = archivesClassMapper.selectById(archivesClass.getParentId());
            if (acBean.getClassType().equals("2")) {
                archivesClass.setParentId(acBean.getParentId());
                buildParentId(archivesClass);
            }
        }
    }


    /**
     * @description: 获取父类ID
     * @author: lig
     * @date: 2021/6/22
     */
    private Long acquireParentId(String fondsId, String typeId, String classTree) {
        String[] ctArr = classTree.split("-");
        Long parentId = 0l;
        if (null != ctArr && ctArr.length > 0) {

            for (int i = 1; i < ctArr.length; i++) {
                QueryWrapper<ArchivesClass> queryWrapper = new QueryWrapper<ArchivesClass>();
//                queryWrapper.eq("classNum", ctArr[i]);
//                queryWrapper.eq(BaseConstants.field_classId, ctArr[i]);
                queryWrapper.eq(BaseConstants.field_typeId, typeId);
                queryWrapper.eq(BaseConstants.field_fondsId, fondsId);
                queryWrapper.eq("parentId", parentId);
                List<ArchivesClass> archivesClasses = archivesClassMapper.selectList(queryWrapper);

                if (i ==1){
                    parentId = 0L ;
                }else{
                    for ( ArchivesClass archivesClasse: archivesClasses ) {
                        ArchivesClass acBean = archivesClasse;

                        if (null != acBean) parentId = acBean.getId() ;
                    }
                }



            }

        }
        return parentId;


    }


    /**
     * @description: 分类号唯一
     * @author: lig
     * @date: 2021/8/12
     */
    private boolean classNumOnly(String fondsId, String typeId, String classNum, Long parentId) {
        QueryWrapper<ArchivesClass> queryWrapper = new QueryWrapper<ArchivesClass>();
//
        queryWrapper.apply("binary classNum={0}" ,classNum);
//        queryWrapper.eq("classNum", classNum);
        queryWrapper.eq("typeId", typeId);
        queryWrapper.eq("fondsId", fondsId);
        queryWrapper.eq("parentId", parentId);
//        if (null != classId && classId > 0) {
//            queryWrapper.notIn("id", classId);
//        }
        int i = archivesClassMapper.selectCount(queryWrapper);
        if (i > 0) return false;
        return true;
    }


    private void insertClassByExcel(List<ClassifysTemplate> list, String fondsId, String typeId) throws BaseException {
//    private void insertClassByExcel(Set<ClassifysTemplate> set ,String fondsNum,String typeNum) throws BaseException {

        if (null != list && !list.isEmpty()) {
            List<Dic> dicList = dicMapper.selectList(null);
            for (ClassifysTemplate oneBean : list) {
                //获取父类ID
                Long parentId = acquireParentId(fondsId, typeId, oneBean.getClassTree());
                if (classNumOnly(fondsId, typeId, oneBean.getClassNum(), parentId)) {

                    ArchivesClass archivesClass = new ArchivesClass();

                    archivesClass.setParentId(parentId);
                    archivesClass.setFondsId(fondsId);
                    archivesClass.setTypeId(typeId);
                    if ("数据列表".equals(oneBean.getClassName())){
                        archivesClass.setTemplate("dataList");
                    }else{
                        archivesClass.setTemplate("fileList");
                    }
//                    archivesClass.setClassName(oneBean.getClassName());
                    archivesClass.setClassType(oneBean.getClassType());
                    archivesClass.setClassName(oneBean.getDataColumn());

//                    if(archivesClass.getClassType().equals("2")){
//                        Dic dic = dicList.stream()
//                                .filter(s->s.getDicValue().equalsIgnoreCase(oneBean.getClassName()))
//                                .findFirst()
//                                .orElse(null);
//                        if(dic != null)archivesClass.setClassName(dic.getDicCode());
////                            archivesClass.setDataColumn(dic.getDicCode());
//                    }else{
//                        archivesClass.setClassName(oneBean.getDataColumn());
//                    }

                    if(archivesClass.getClassType().equals("2")){
                        switch ( archivesClass.getClassName()){
                            case "保管期限" :  archivesClass.setDataColumn("storagePeriod");break;
                            case "年度" :  archivesClass.setDataColumn("archivalYear");break;
                            case "开放状态" :  archivesClass.setDataColumn("openState");
                        }
                    }else {
                        archivesClass.setClassNum(oneBean.getClassNum());
                        archivesClass.setTreeStr(oneBean.getClassTree().substring(2).replace("-", "·"));

                    }
                    archivesClass.setIsCatalog("1");
                    archivesClass.setSort(0);
                    int rows = archivesClassMapper.insert(archivesClass);
                    if (rows < 1)
                        throw new BaseException(ResultCode.RESULT_SUCCESS.getCode(), "新增失败,分类树信息：" + oneBean.getClassTree());
                }
            }

        }
    }


}
